package com.kye.express.business.order.scan_code_add_order;

import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
import android.databinding.DataBindingUtil;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.view.View;

import com.afollestad.materialdialogs.MaterialDialog;
import com.bigkoo.pickerview.TimePickerView;
import com.jakewharton.rxbinding2.view.RxView;
import com.jakewharton.rxbinding2.widget.RxCompoundButton;
import com.jakewharton.rxbinding2.widget.RxTextView;
import com.kye.base.DebounceObservableTransformer;
import com.kye.datetimepicker.DateTimePicker;
import com.kye.express.R;
import com.kye.express.business.base.BaseAppCompatActivity;
import com.kye.express.business.order.AddOrderSuccessActivity;
import com.kye.express.business.order.remark.RemarkActivity;
import com.kye.express.business.order.scan_code_address.ScanCodeAddressEditActivity;
import com.kye.express.business.order.scan_code_addresses.ScanCodeAddressListActivity;
import com.kye.express.databinding.ActivityScanCodeAddOrderBinding;
import com.kye.express.utils.ToolbarManager;
import com.kye.express.view.KyeProgressDialog;
import com.kye.express.view.ToastManager;
import com.kye.model.UserSession;
import com.kye.model.bean.order.scan_code_order.ScanCodeAddOrderBean;
import com.kye.model.bean.order.scan_code_order.ScanCodeOrderAddress;
import com.kye.model.bean.user.User;

import java.util.Calendar;
import java.util.Date;
import java.util.concurrent.TimeUnit;

import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function6;
import io.reactivex.functions.Function9;

public class ScanCodeAddOrderActivity extends BaseAppCompatActivity implements ScanCodeAddOrderContract.ScanCodeAddOrderView {
    private static final String KEY_CUSTOMERCODE = "KEY_CUSTOMERCODE";
    private static final String KEY_ADDRESS = "KEY_ADDRESS";

    private static final int REQUEST_CODE_SEND_ADDRESS = 1;
    private static final int REQUEST_CODE_RECEIVE_ADDRESS = 2;
    private static final int REQUEST_CODE_REMARK = 3;

    private ActivityScanCodeAddOrderBinding mBinding;
    private MaterialDialog mServiceModeDialog;
    private TimePickerView mTimePickerView;
    private MaterialDialog mWayOfPayingDialog;
    private ScanCodeAddOrderContract.ScanCodeAddOrderPresenter mPresenter;
    private String mCustomerCode;
    private Dialog mDialog;

    public static void startActivity(Context context, String customerCode, ScanCodeOrderAddress addressData) {
        context.startActivity(
                new Intent(context, ScanCodeAddOrderActivity.class)
                        .putExtra(KEY_CUSTOMERCODE, customerCode)
                        .putExtra(KEY_ADDRESS, addressData)
        );
    }

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mBinding = DataBindingUtil.setContentView(this, R.layout.activity_scan_code_add_order);

        mCustomerCode = getIntent().getStringExtra(KEY_CUSTOMERCODE);

        initView();
        initEvent();
        initData();
    }

    private void initView() {

    }

    private void initEvent() {
        ToolbarManager.setToolbar(this, mBinding.toolbar);

        RxView.clicks(mBinding.relativeLayoutSendAddress)
                .compose(new DebounceObservableTransformer<>())
                .compose(bindToLifecycle())
                .subscribe(new Consumer<Object>() {
                    @Override
                    public void accept(Object o) throws Exception {
                        ScanCodeAddressEditActivity.startActivityForResult(ScanCodeAddOrderActivity.this, mBinding.getSendAddress(), ScanCodeAddressEditActivity.SEND_ADDRESS, REQUEST_CODE_SEND_ADDRESS);
                    }
                });

        RxView.clicks(mBinding.buttonSendAddresses)
                .compose(new DebounceObservableTransformer<>())
                .compose(bindToLifecycle())
                .subscribe(new Consumer<Object>() {
                    @Override
                    public void accept(Object o) throws Exception {
                        ScanCodeAddressListActivity.startActivityForResult(ScanCodeAddOrderActivity.this, ScanCodeAddressEditActivity.SEND_ADDRESS, REQUEST_CODE_SEND_ADDRESS);
                    }
                });

        RxView.clicks(mBinding.relativeLayoutReceiveAddress)
                .compose(new DebounceObservableTransformer<>())
                .compose(bindToLifecycle())
                .subscribe(new Consumer<Object>() {
                    @Override
                    public void accept(Object o) throws Exception {
                        ScanCodeAddressEditActivity.startActivityForResult(ScanCodeAddOrderActivity.this, mBinding.getReceiveAddress(), ScanCodeAddressEditActivity.RECEIVE_ADDRESS, REQUEST_CODE_RECEIVE_ADDRESS);
                    }
                });

        RxView.clicks(mBinding.buttonReceiveAddresses)
                .compose(new DebounceObservableTransformer<>())
                .compose(bindToLifecycle())
                .subscribe(new Consumer<Object>() {
                    @Override
                    public void accept(Object o) throws Exception {
                        ScanCodeAddressListActivity.startActivityForResult(ScanCodeAddOrderActivity.this, ScanCodeAddressEditActivity.RECEIVE_ADDRESS, REQUEST_CODE_RECEIVE_ADDRESS);
                    }
                });

        RxView.clicks(mBinding.linearLayoutServiceMode)
                .compose(new DebounceObservableTransformer<>())
                .compose(bindToLifecycle())
                .subscribe(new Consumer<Object>() {
                    @Override
                    public void accept(Object o) throws Exception {
                        if (mServiceModeDialog == null) {
                            mServiceModeDialog = new MaterialDialog.Builder(ScanCodeAddOrderActivity.this)
                                    .items(R.array.scan_code_add_order_service_mode_items)
                                    .itemsCallback(new MaterialDialog.ListCallback() {
                                        @Override
                                        public void onSelection(MaterialDialog dialog, View itemView, int position, CharSequence text) {
                                            mBinding.setServiceMode(text.toString().trim());
                                        }
                                    })
                                    .build();
                        }
                        mServiceModeDialog.show();
                    }
                });

        RxView.clicks(mBinding.linearLayoutGoodTime)
                .compose(new DebounceObservableTransformer<>())
                .compose(bindToLifecycle())
                .subscribe(new Consumer<Object>() {
                    @Override
                    public void accept(Object o) throws Exception {
                        mTimePickerView = DateTimePicker.show(ScanCodeAddOrderActivity.this, true, true, true, true, true, false, Calendar.getInstance(), null, new DateTimePicker.DateTimeCallBack() {
                            @Override
                            public void callBack(Date date) {
                                if (date.getTime() < System.currentTimeMillis()) {
                                    ToastManager.show(ScanCodeAddOrderActivity.this, "货好时间不能早于现在");
                                    return;
                                }
                                mBinding.setGoodTime(date);
                            }
                        });
                    }
                });

        RxView.clicks(mBinding.linearLayoutWayOfPaying)
                .compose(new DebounceObservableTransformer<>())
                .compose(bindToLifecycle())
                .subscribe(new Consumer<Object>() {
                    @Override
                    public void accept(Object o) throws Exception {
                        if (mWayOfPayingDialog == null) {
                            mWayOfPayingDialog = new MaterialDialog.Builder(ScanCodeAddOrderActivity.this)
                                    .items(R.array.scan_code_add_order_way_of_paying_items)
                                    .itemsCallback(new MaterialDialog.ListCallback() {
                                        @Override
                                        public void onSelection(MaterialDialog dialog, View itemView, int position, CharSequence text) {
                                            mBinding.setWayOfPaying(text.toString().trim());
                                        }
                                    })
                                    .build();
                        }
                        mWayOfPayingDialog.show();
                    }
                });

        RxView.clicks(mBinding.linearLayoutRemark)
                .compose(new DebounceObservableTransformer<>())
                .compose(bindToLifecycle())
                .subscribe(new Consumer<Object>() {
                    @Override
                    public void accept(Object o) throws Exception {
                        RemarkActivity.startActivityForResult(ScanCodeAddOrderActivity.this, mBinding.textViewRemark.getText().toString().trim(), REQUEST_CODE_REMARK);
                    }
                });


        final Observable<CharSequence> textViewSendAddress = RxTextView.textChanges(mBinding.textViewSendAddress).cache();
        final Observable<CharSequence> textViewReceiveAddress = RxTextView.textChanges(mBinding.textViewReceiveAddress).cache();
        final Observable<CharSequence> textViewServiceMode = RxTextView.textChanges(mBinding.textViewServiceMode).cache();
        final Observable<CharSequence> editTextWeight = RxTextView.textChanges(mBinding.editTextWeight).cache();
        final Observable<CharSequence> editTextTotalNumber = RxTextView.textChanges(mBinding.editTextTotalNumber).cache();

        Observable.combineLatest(
                Observable.just(mCustomerCode),
                textViewSendAddress,
                textViewReceiveAddress,
                textViewServiceMode,
                editTextWeight,
                editTextTotalNumber,
                new Function6<String, CharSequence, CharSequence, CharSequence, CharSequence,CharSequence, Boolean>() {
                    @Override
                    public Boolean apply(String s, CharSequence charSequence, CharSequence charSequence2, CharSequence charSequence3, CharSequence charSequence4, CharSequence charSequence5) throws Exception {
                        return !TextUtils.isEmpty(s) &&
                                !TextUtils.isEmpty(charSequence) &&
                                !TextUtils.isEmpty(charSequence2) &&
                                !TextUtils.isEmpty(charSequence3) &&
                                !TextUtils.isEmpty(charSequence4) &&
                                !TextUtils.isEmpty(charSequence5);

                    }
                })
                .throttleLast(500, TimeUnit.MILLISECONDS)
                .compose(bindToLifecycle())
                .subscribe(new Consumer<Boolean>() {
                    @Override
                    public void accept(Boolean aBoolean) throws Exception {
                        if (aBoolean) {
                            mPresenter.getQuote(
                                    mCustomerCode,
                                    mBinding.getSendAddress().getProvince(),
                                    mBinding.getSendAddress().getCity(),
                                    mBinding.getReceiveAddress().getProvince(),
                                    mBinding.getReceiveAddress().getCity(),
                                    mBinding.getSendAddress().getContactsPhone(),
                                    mBinding.getServiceMode(),
                                    mBinding.editTextWeight.getText().toString().trim(),
                                    mBinding.editTextTotalNumber.getText().toString().trim()
                            );
                        } else {
                            mBinding.setQuote(0);
                            mBinding.setSupportValue(0);
                        }
                    }
                });

        Observable.combineLatest(
                textViewSendAddress,
                textViewReceiveAddress,
                RxTextView.textChanges(mBinding.editTextCommodities),
                textViewServiceMode,
                RxTextView.textChanges(mBinding.textViewGoodTime),
                RxTextView.textChanges(mBinding.textViewWayOfPaying),
                editTextTotalNumber,
                editTextWeight,
                RxCompoundButton.checkedChanges(mBinding.checkBoxProtocol),
                new Function9<CharSequence, CharSequence, CharSequence, CharSequence, CharSequence, CharSequence, CharSequence, CharSequence, Boolean, Boolean>() {
                    @Override
                    public Boolean apply(CharSequence charSequence, CharSequence charSequence2, CharSequence charSequence3, CharSequence charSequence4, CharSequence charSequence5, CharSequence charSequence6, CharSequence charSequence7, CharSequence charSequence8, Boolean aBoolean) throws Exception {
                        return !TextUtils.isEmpty(charSequence) &&
                                !TextUtils.isEmpty(charSequence2) &&
                                !TextUtils.isEmpty(charSequence3) &&
                                !TextUtils.isEmpty(charSequence4) &&
                                !TextUtils.isEmpty(charSequence5) &&
                                !TextUtils.isEmpty(charSequence6) &&
                                !TextUtils.isEmpty(charSequence7) &&
                                !TextUtils.isEmpty(charSequence8) &&
                                aBoolean;
                    }
                }
        )
                .compose(bindToLifecycle())
                .subscribe(new Consumer<Boolean>() {
                    @Override
                    public void accept(Boolean aBoolean) throws Exception {
                        mBinding.buttonSubmit.setEnabled(aBoolean);
                    }
                });

        RxView.clicks(mBinding.buttonSubmit)
                .compose(new DebounceObservableTransformer<>())
                .compose(bindToLifecycle())
                .subscribe(new Consumer<Object>() {
                    @Override
                    public void accept(Object o) throws Exception {
                        mPresenter.submit(
                                mBinding.getSendAddress().getContacts(),
                                mBinding.getSendAddress().getContactsPhone(),
                                mBinding.getSendAddress().getAddress(),
                                mBinding.editTextCommodities.getText().toString().trim(),
                                mBinding.getServiceMode(),
                                mBinding.getRemark(),
                                mBinding.getReceiveAddress().getContacts(),
                                mBinding.getReceiveAddress().getContactsPhone(),
                                mBinding.getReceiveAddress().getAddress(),
                                mBinding.getSendAddress().getProvince(),
                                mBinding.getSendAddress().getCity(),
                                mBinding.getReceiveAddress().getProvince(),
                                mBinding.getReceiveAddress().getCity(),
                                mBinding.editTextCostOfGoods.getText().toString().trim(),
                                mCustomerCode,
                                mBinding.editTextWeight.getText().toString().trim(),
                                mBinding.editTextTotalNumber.getText().toString().trim(),
                                mBinding.getWayOfPaying(),
                                mBinding.getGoodTime()
                        );
                    }
                });
    }

    private void initData() {
        final ScanCodeOrderAddress address = (ScanCodeOrderAddress) getIntent().getSerializableExtra(KEY_ADDRESS);
        onSendAddress(address);
        mPresenter = new ScanCodeAddOrderContract.ScanCodeAddOrderPresenter();
        mPresenter.bind(this);
        mPresenter.checkAddress(address);
    }

    @Override
    public void onSendAddress(ScanCodeOrderAddress address) {
        mBinding.setSendAddress(address);
    }

    @Override
    public void onSuccess(ScanCodeAddOrderBean scanCodeAddOrderBean) {
        UserSession.getInstance()
                .getUserForRx()
                .compose(bindToLifecycleDestroy())
                .subscribeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer<User>() {
                    @Override
                    public void accept(User user) throws Exception {
                        AddOrderSuccessActivity.startActivity(ScanCodeAddOrderActivity.this, user.getPhone(), scanCodeAddOrderBean.getBillNo());
                        finish();
                    }
                });
    }

    @Override
    public void onQuote(double quote) {
        mBinding.setQuote(quote);

        double supportValue = quote * 0.004;
        if (supportValue < 10) supportValue = 10;

        mBinding.setSupportValue(supportValue);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQUEST_CODE_SEND_ADDRESS && resultCode == RESULT_OK) {
            onSendAddress((ScanCodeOrderAddress) data.getSerializableExtra(ScanCodeAddressEditActivity.KEY_ADDRESS));
        }
        if (requestCode == REQUEST_CODE_RECEIVE_ADDRESS && resultCode == RESULT_OK) {
            mBinding.setReceiveAddress((ScanCodeOrderAddress) data.getSerializableExtra(ScanCodeAddressEditActivity.KEY_ADDRESS));
        }
        if (requestCode == REQUEST_CODE_REMARK && resultCode == RESULT_OK && data != null) {
            mBinding.setRemark(data.getStringExtra(RemarkActivity.KEY_REMARK));
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mServiceModeDialog != null && mServiceModeDialog.isShowing())
            mServiceModeDialog.dismiss();
        if (mTimePickerView != null && mTimePickerView.isShowing()) mTimePickerView.dismiss();
        if (mWayOfPayingDialog != null && mWayOfPayingDialog.isShowing())
            mWayOfPayingDialog.dismiss();
    }

    @Override
    public void onError() {
        ToastManager.show(this, R.string.common_net_error);
    }

    @Override
    public void onError(String msg) {
        ToastManager.show(this, msg);
    }

    @Override
    public void onLoading() {
        mDialog = KyeProgressDialog.show(this, mDialog);
    }

    @Override
    public void onLoaded() {
        KyeProgressDialog.dismiss(mDialog);
    }
}
